package com.quectel.emp.controller.schedulingapply;

import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.business.common.dept.DeptPersonMsgBusiness;
import com.quectel.business.common.file.FileBusiness;
import com.quectel.business.common.schedulingapply.SchedulingApplyBusiness;
import com.quectel.constant.core.scheduling.SchedulingApplyConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.dept.service.DeptPersonService;
import com.quectel.core.module.scheduling.service.SchedulingAuditPipelineSeqDeptPersonService;
import com.quectel.core.module.scheduling.service.SchedulingAuditPipelineService;
import com.quectel.core.module.schedulingapply.dto.SchedulingApplyRecordAuditLogDto;
import com.quectel.core.module.schedulingapply.dto.SchedulingApplyRecordAuditPersonDto;
import com.quectel.core.module.schedulingapply.dto.SchedulingApplyRecordDto;
import com.quectel.core.module.schedulingapply.dto.vo.SchedulingApplyAuditRsp;
import com.quectel.core.module.schedulingapply.dto.vo.SchedulingApplyCountVO;
import com.quectel.core.module.schedulingapply.service.SchedulingApplyRecordAuditLogService;
import com.quectel.core.module.schedulingapply.service.SchedulingApplyRecordAuditPersonService;
import com.quectel.core.module.schedulingapply.service.SchedulingApplyRecordService;
import com.quectel.emp.controller.BaseController;
import com.quectel.emp.util.SessionHolder;
import com.quectel.emp.vo.schedulingapply.SchedulingAuditReqVo;
import com.quectel.util.common.Page;
import com.quectel.util.common.Request;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhangheng
 * @email nolan.zhang@quectel.com
 * @date 2023/07/13 19:14
 */
@RestController
@RequestMapping("schedulingApplyRecordAudit")
@Tag(name = "SchedulingApplyRecordAuditController", description = "申请记录审批相关api")
public class SchedulingApplyRecordAuditController extends BaseController {

    @DubboReference
    private SchedulingApplyRecordService schedulingApplyRecordService;
    @DubboReference
    private SchedulingAuditPipelineService schedulingAuditPipelineService;
    @DubboReference
    private SchedulingApplyRecordAuditPersonService schedulingApplyRecordAuditPersonService;
    @DubboReference
    private SchedulingAuditPipelineSeqDeptPersonService schedulingAuditPipelineSeqDeptPersonService;
    @DubboReference
    private DeptPersonService deptPersonService;


    @Autowired
    private SchedulingApplyBusiness schedulingApplyBusiness;
    @Autowired
    private FileBusiness fileBusiness;
    @Autowired
    private DeptPersonMsgBusiness deptPersonMsgBusiness;
    @Autowired
    private SchedulingApplyRecordAuditLogService schedulingApplyRecordAuditLogService;


    /**
     * 本人的待审核记录统计
     */
    @GetMapping("applyRecordAuditCount")
    @Operation(summary = "本人的待审核记录统计")
    public Response<List<SchedulingApplyCountVO>> applyRecordAuditCount(
    ) {
        SessionHolder.checkEmp();
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        request.put(LambdaUtil.getFieldName(SchedulingApplyRecordDto::getTenantId), SessionHolder.getEmp().getTenantId());
        request.put(LambdaUtil.getFieldName(SchedulingApplyRecordDto::getVillageId), SessionHolder.getEmp().getVillageId());
        request.put(LambdaUtil.getFieldName(SchedulingApplyRecordAuditPersonDto::getAuditDeptPersonId), SessionHolder.getEmp().getId());
        request.put(SchedulingApplyConstants.IS_CURRENT, SystemConstants.YES.toString());

        //审核中的记录
        request.put(SystemConstants.STATUSES, SchedulingApplyConstants.AUDITING_STATUSES);

        List<SchedulingApplyCountVO> schedulingApplyCountVOS = schedulingApplyRecordService.applyRecordAuditCount(request.getParams());

        return Response.<List<SchedulingApplyCountVO>>ok().wrap(schedulingApplyCountVOS);
    }

    /**
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("list")
    @Operation(summary = "待审核列表查询")
    public Response<Page<SchedulingApplyRecordDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize,
            @Parameter(description = "1待审核2已审批") @RequestParam String typeFlag,
            @Parameter(description = "审批类型") @RequestParam(required = false) Byte applyType
    ) {
        SessionHolder.checkEmp();
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        if (typeFlag.equals(SchedulingApplyConstants.AUDITING)) {
            request.put(SystemConstants.STATUSES, SchedulingApplyConstants.AUDITING_STATUSES);
            //待本人审核 节点应该到本人了
            request.put(SchedulingApplyConstants.IS_CURRENT, SystemConstants.YES.toString());
        } else if (typeFlag.equals(SchedulingApplyConstants.FINISHED)) {
            request.put(SystemConstants.STATUSES, SchedulingApplyConstants.AUDIT_FINISHED_STATUSES);
            //审批过的需要看日志
            request.put(SchedulingApplyConstants.IS_AUDITED, SystemConstants.YES.toString());
            //已结束,不用再过滤isCurrent
        } else {
            return Response.error("查询范围不正确");
        }
        request.put(LambdaUtil.getFieldName(SchedulingApplyRecordDto::getTenantId), SessionHolder.getEmp().getTenantId());
        request.put(LambdaUtil.getFieldName(SchedulingApplyRecordDto::getVillageId), SessionHolder.getEmp().getVillageId());
        request.put(LambdaUtil.getFieldName(SchedulingApplyRecordDto::getApplyType), applyType);
        request.put(LambdaUtil.getFieldName(SchedulingApplyRecordAuditPersonDto::getAuditDeptPersonId), SessionHolder.getEmp().getId());

        int total = schedulingApplyRecordService.queryRecordTotal(request.getParams());

        List<SchedulingApplyRecordDto> list = null;
        if (total > 0) {
            list = schedulingApplyRecordService.queryRecordList(request.getParams());
            list.forEach(schedulingApplyRecordDto -> {
                //填充表单数据
                SchedulingApplyRecordDto.BaseFormData formData = schedulingApplyBusiness.getFormData(schedulingApplyRecordDto.getApplyType(), schedulingApplyRecordDto.getFormDataJson());
                schedulingApplyRecordDto.setFormData(formData);
            });
        } else {
            list = new ArrayList<>();
        }
        Page<SchedulingApplyRecordDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<SchedulingApplyRecordDto>>ok().wrap(page);

    }

    /**
     * 编辑查询反显
     *
     * @param id
     * @return
     */
    @GetMapping("info/{id}")
    @Operation(summary = "查询审核记录详情")
    public Response<SchedulingApplyRecordDto> info(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        params.put(LambdaUtil.getFieldName(SchedulingApplyRecordAuditPersonDto::getApplyRecordId), id);
        params.put(LambdaUtil.getFieldName(SchedulingApplyRecordAuditPersonDto::getAuditDeptPersonId), SessionHolder.getEmp().getId());
        if (schedulingApplyRecordAuditPersonService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        SchedulingApplyRecordDto schedulingApplyRecordDto = schedulingApplyRecordService.selectById(id);
        if (schedulingApplyRecordDto == null) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        //填充表单数据
        SchedulingApplyRecordDto.BaseFormData formData = schedulingApplyBusiness.getFormData(schedulingApplyRecordDto.getApplyType(), schedulingApplyRecordDto.getFormDataJson());
        schedulingApplyRecordDto.setFormData(formData);

        List<SchedulingApplyRecordAuditLogDto> auditLogs = schedulingApplyBusiness.getAuditLogs(schedulingApplyRecordDto);
        schedulingApplyRecordDto.setAuditLogs(auditLogs);
        //是否需要审核
        schedulingApplyRecordDto.setNeedAudit(checkIfAudit(id, schedulingApplyRecordDto.getCurrentAtSeq(), SessionHolder.getEmp().getId()));


        return Response.<SchedulingApplyRecordDto>ok().wrap(schedulingApplyRecordDto);
    }


    @PostMapping("auditReq")
    @Operation(summary = "审核请求")
    public Response<Object> auditReq(
            @RequestBody SchedulingAuditReqVo reqVo) {
        SessionHolder.checkEmp();

        //是否到当前节点 是否有审核权限
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put(LambdaUtil.getFieldName(SchedulingApplyRecordAuditPersonDto::getAuditDeptPersonId), SessionHolder.getEmp().getId());
        queryParam.put(SchedulingApplyConstants.IS_CURRENT, SystemConstants.YES.toString());
        queryParam.put(LambdaUtil.getFieldName(SchedulingApplyRecordAuditPersonDto::getApplyRecordId), reqVo.getRecordId());
        queryParam.put(LambdaUtil.getFieldName(SchedulingApplyRecordDto::getStatus), SchedulingApplyConstants.INIT_STATUS.toString());
        if (schedulingApplyRecordService.queryRecordTotal(queryParam) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        SchedulingApplyRecordDto schedulingApplyRecordDto = schedulingApplyRecordService.selectById(reqVo.getRecordId());
        if (schedulingApplyRecordDto == null) {
            return Response.error("申请记录不存在");
        }
        //只有待审核状态才可以审核
        if (!SchedulingApplyConstants.INIT_STATUS.equals(schedulingApplyRecordDto.getStatus())) {
            return Response.error("该审核记录不可以提交审批");
        }
        //如果已经结束 则不能操作
        if (SchedulingApplyConstants.CURRENT_AT_SEQ_OF_CLOSE.equals(schedulingApplyRecordDto.getCurrentAtSeq())) {
            return Response.error("流程已结束不可以操作");
        }

        SchedulingApplyAuditRsp auditRsp = schedulingApplyRecordService.audit(reqVo.getRecordId(), SessionHolder.getEmp().getId(), reqVo.getStatus(), reqVo.getRemark());
        if (auditRsp == null || !SystemConstants.YES.equals(auditRsp.getResult())) {
            return Response.error("审核失败");
        }

        schedulingApplyBusiness.pushMsg(schedulingApplyRecordDto, reqVo.getStatus(), auditRsp.getNextSeq());
        return Response.ok();
    }

    private Byte checkIfAudit(Long recordId, Integer currentAtSeq, Long personId) {
        if (SchedulingApplyConstants.CURRENT_AT_SEQ_OF_CLOSE.equals(currentAtSeq)) {
            return SystemConstants.NO;
        } else {
            List<SchedulingApplyRecordAuditPersonDto> schedulingApplyRecordAuditPersonDtos = schedulingApplyRecordAuditPersonService.selectByRecordAndSeq(recordId, currentAtSeq);
            if (CollectionUtils.isEmpty(schedulingApplyRecordAuditPersonDtos)) {
                return SystemConstants.NO;
            } else {
                SchedulingApplyRecordAuditPersonDto schedulingApplyRecordAuditPersonDto = schedulingApplyRecordAuditPersonDtos.stream().filter(dto -> dto.getAuditDeptPersonId().equals(personId)).findFirst().orElse(null);
                if (schedulingApplyRecordAuditPersonDto == null) {
                    return SystemConstants.NO;
                } else {
                    return SystemConstants.YES;
                }
            }
        }
    }


}
